if (typeof window.medbiq === 'undefined') window.medbiq = {};
if (typeof medbiq.mvp === 'undefined') window.medbiq.mvp = {};
window.medbiq.mvp.log = (function () {
 var
  VERSION = "2010-03-01",
  listeners = {},
  implementations = [];

 var testImplementation = function (implementation) {
  if (typeof implementation.eventReceived !== 'function')
     throw "Implementation does not implement the function eventReceived.";
  if (typeof implementation.isNamespaceSupported !== 'function')
     throw "Implementation does not implement the function isNamespaceSupported.";
  };

  var fireEvent = function (e) {
  e.date = new Date ();
  for (var i = 0; i < implementations.length; i++)
      if (implementations[i].isNamespaceSupported (e.ns))
         implementations[i].eventReceived (e);
  };

 var NS_ACTIVITY_MODEL = "http://ns.medbiq.org/activitymodel/v1/",
     NS_DATAAVAILABILITY_MODEL = "http://ns.medbiq.org/dataavailabilitymodel/v1/",
     NS_VIRTUALPATIENTDATA_MODEL = "http://ns.medbiq.org/virtualpatientdata/v1/";


 return {
  /** Namespaces */
  NS_ACTIVITY_MODEL: NS_ACTIVITY_MODEL,
  NS_DATAAVAILABILITY_MODEL: NS_DATAAVAILABILITY_MODEL,
  NS_VIRTUALPATIENTDATA_MODEL: NS_VIRTUALPATIENTDATA_MODEL,


 Type: {
  ACTIVITY_NODE_SHOWN: {
   ns: NS_ACTIVITY_MODEL,
   id: 1
   },
  DAMN_NODE_SHOWN: {
   ns:  NS_DATAAVAILABILITY_MODEL,
   id: 2 
   },
  DAMN_NODE_ITEM_SHOWN: {
   ns:  NS_DATAAVAILABILITY_MODEL,
   id: 3 
   },
  DAMN_NODE_ITEM_TRIGGERED: {
   ns:  NS_DATAAVAILABILITY_MODEL,
   id: 4
   },
  VPD_TEXT_SHOWN: {
   ns: NS_VIRTUALPATIENTDATA_MODEL,
   id: 5
   }, 
  MEDICATION_SHOWN: {
   ns: NS_VIRTUALPATIENTDATA_MODEL,
   id: 6
   },
  INTERVIEW_ITEM_SHOWN: {
   ns: NS_VIRTUALPATIENTDATA_MODEL,
   id: 7
   },
  PHYSICAL_EXAM_SHOWN: {
   ns: NS_VIRTUALPATIENTDATA_MODEL,
   id: 8
   },
  DIAGNOSTIC_TEST_SHOWN: {
   ns: NS_VIRTUALPATIENTDATA_MODEL,
   id: 9
   },
  DIAGNOSIS_SHOWN: {
   ns: NS_VIRTUALPATIENTDATA_MODEL,
   id: 10
   },
  INTERVENTION_SHOWN: {
   ns: NS_VIRTUALPATIENTDATA_MODEL,
   id: 11
   }
  },

  getTypeName: function (ns, id) {
   if (!ns)
      throw 'No namespace specified';
   if (!id)
      throw 'No id specified';
   for (var x in this.Type) {
       if (this.Type[x].ns === ns && this.Type[x].id === id)
          return x;
       }
   return x;
   },

  /** Delivers the version of the API */
  getVersion: function () { return VERSION; },

  /** Registers a implementation */
  registerImplementation: function (implementation) {
   testImplementation (implementation);
   implementations.push (implementation);
   },

  fireSpecEvent: function (e) {
   var namespace = e.namespace ? e.namespace : e.ns ? e.ns : e.type ? (e.type.namespace ? type.namespace : e.type.ns ? e.type.ns : null) : null;
   var typeID = e.type ? e.type.id ? e.type.id : e.type : null;
   if (!typeID) throw 'No type specified';
   if (!namespace) 
      for (var x in this.Type)
          if (this.Type[x].id == typeID) {
	     namespace = this.Type[x].ns;
             break;
	     }
   if (!namespace)
      throw 'No namespace specified';
   if (!e.elementID)
      throw 'No elementID specified';
   if (!e.userID)
      throw 'No userID specified';

   // Test, if the typeID and Namespace is a spec event
   if (!this.getTypeName (namespace, typeID))
      throw 'No spec event found for this namespace ('+namespace+') and typeID ('+typeID+')';
   fireEvent ({ ns: namespace, typeID: typeID, elementID: e.elementID, data: e.data, userID: e.userID });
   },

  fireForeignEvent: function (e) {
   if (!e.namespace && !e.ns)
      throw 'No namespaces specified';
   if (!e.elementID)
      throw 'No elementID specified';
   if (!e.userID)
      throw 'No userID specified';
   if (!e.typeID)
      throw 'No typeID specified';
   fireEvent ({ ns: e.namespace || e.ns, typeID: e.typeID, elementID: e.elementID, data: e.data, userID: e.userID });
   }
  };
 }) ();

/**
 * Implementations must implement the following methods:
 *
 * 1. eventReceived: function (object)
 *    object: {
 *             ns: namespace,
 *             date: the date object,
 *             typeID: the type of the event,
 *             elementID: the id of the element,
 *             data: additional data
 *            }
 * 2. isNamespaceSupported: function (string)
 * 3. 
 */

if (typeof window.medbiq === 'undefined') window.medbiq = {};
if (typeof window.medbiq.mvp === 'undefined') window.medbiq.mvp = {};
if (typeof window.medbiq.mvp.logImplementations == 'undefined') window.medbiq.mvp.logImplementations = {};
window.medbiq.mvp.logImplementations.scorm = (function () {
 if (typeof ScormProcessInitialize !== 'undefined') {
    var log = window.medbiq.mvp.log;
    ScormProcessInitialize ();
 
    try {
        return {
         eventReceived: function (e) {
         },
        isNamespaceSupported: function (ns) {
         return ns === log.NS_ACTIVITY_MODEL || ns === log.NS_DATAAVAILABILITY_MODEL || ns === log.NS_VIRTUALPATIENTDATA_MODEL;
         }
        };
        } finally { 
                  window.medbiq.mvp.log.registerImplementation (window.medbiq.mvp.logImplementations.scorm);
                  }
    }
 }) ();
